using MediatR;
using Microsoft.EntityFrameworkCore;
using SupplierCustomerManagement.Infrastructure;
using SupplierCustomerManagement.Read.API.Applications.Commands.reportforms;
using SupplierCustomerManagement.Read.API.Dtos.ReportForms;

namespace SupplierCustomerManagement.Read.API.Applications.CommandHandlters.reportforms
{
    public class GetProductionOverviewQueryHandler : IRequestHandler<GetProductionOverviewQuery, ProductionOverviewDto>
    {
        private readonly SupplierDbContext _db;
        private readonly ILogger<GetProductionOverviewQueryHandler> _logger;

        public GetProductionOverviewQueryHandler(SupplierDbContext db, ILogger<GetProductionOverviewQueryHandler> logger)
        {
            _db = db;
            _logger = logger;
        }

        public async Task<ProductionOverviewDto> Handle(GetProductionOverviewQuery request, CancellationToken cancellationToken)
        {
            // 仅实现按月聚合（Period=month）。若未提供月份，默认取当前月份。
            var period = string.IsNullOrWhiteSpace(request.Period) ? "month" : request.Period.Trim().ToLower();
            DateTime startDate;
            DateTime endDate;

            if (period == "year")
            {
                var year = DateTime.Today.Year;
                startDate = new DateTime(year, 1, 1);
                endDate = new DateTime(year, 12, 31, 23, 59, 59, 999);
            }
            else
            {
                // 默认 month
                if (!string.IsNullOrWhiteSpace(request.Month) && DateTime.TryParse(request.Month + "-01", out var monthDate))
                {
                    startDate = new DateTime(monthDate.Year, monthDate.Month, 1);
                }
                else
                {
                    var today = DateTime.Today;
                    startDate = new DateTime(today.Year, today.Month, 1);
                }
                endDate = startDate.AddMonths(1).AddTicks(-1);
            }

            var query = _db.ProductionSummaries.AsNoTracking()
                .Where(x => x.ReportDate >= startDate && x.ReportDate <= endDate);

            if (request.FarmId.HasValue)
            {
                var farmId = request.FarmId.Value;
                query = query.Where(x => x.FarmId == farmId);
            }

            // 聚合
            var aggregates = await query
                .GroupBy(x => 1)
                .Select(g => new
                {
                    TotalEwes = g.Sum(x => x.TotalEwes) ?? 0,
                    BreedingEwes = g.Sum(x => x.BreedingEwes) ?? 0,
                    PregnantEwes = g.Sum(x => x.PregnantEwes) ?? 0,
                    LambingEwes = g.Sum(x => x.LambingEwes) ?? 0,
                    TotalLambs = g.Sum(x => x.TotalLambs) ?? 0,
                    LiveLambs = g.Sum(x => x.LiveLambs) ?? 0,
                    BreedingRate = g.Average(x => x.BreedingRate) ?? 0,
                    PregnancyRate = g.Average(x => x.PregnancyRate) ?? 0,
                    LambingRate = g.Average(x => x.LambingRate) ?? 0,
                    SurvivalRate = g.Average(x => x.SurvivalRate) ?? 0
                })
                .FirstOrDefaultAsync(cancellationToken) ?? new
                {
                    TotalEwes = 0,
                    BreedingEwes = 0,
                    PregnantEwes = 0,
                    LambingEwes = 0,
                    TotalLambs = 0,
                    LiveLambs = 0,
                    BreedingRate = 0m,
                    PregnancyRate = 0m,
                    LambingRate = 0m,
                    SurvivalRate = 0m
                };

            var dto = new ProductionOverviewDto
            {
                Period = period,
                Month = period == "month" ? startDate.ToString("yyyy-MM") : string.Empty,
                // 以下几个板块没有详细的原子表，这里用汇总字段做近似输出。
                EweInventoryChange = new EweInventoryChangeSummaryDto
                {
                    Beginning = aggregates.TotalEwes, // 近似展示
                    ReserveToEwe = 0,
                    Purchase = 0,
                    AllocationIn = 0,
                    Death = 0,
                    Culling = 0,
                    Sales = 0,
                    AllocationOut = 0,
                    Other = 0,
                    Ending = aggregates.TotalEwes
                },
                LambInventory = new LambInventorySummaryDto
                {
                    Beginning = aggregates.TotalLambs,
                    Lambing = aggregates.LiveLambs,
                    Purchase = 0,
                    AllocationIn = 0,
                    InventoryIn = 0,
                    RecoveryIn = 0,
                    ReserveIn = 0,
                    Death = 0,
                    Sales = 0,
                    AllocationOut = 0,
                    InventoryOut = 0,
                    SeedlingOut = 0,
                    Other = 0,
                    Ending = aggregates.TotalLambs
                },
                Breeding = new BreedingStatsDto
                {
                    // 用 BreedingEwes 近似总配种头数
                    ReserveMating = 0,
                    WeaningMating = 0,
                    ReturnMating = 0,
                    NotPregnantMating = 0,
                    EmptyMating = 0,
                    AbortionMating = 0,
                    OtherMating = 0,
                    TotalMating = aggregates.BreedingEwes
                },
                Lambing = new LambingStatsDto
                {
                    LitterCount = aggregates.LambingEwes,
                    HealthyLamb = aggregates.LiveLambs,
                    WeakLamb = 0,
                    Stillbirth = 0,
                    Mummy = 0,
                    Deformed = 0,
                    Abnormal = 0,
                    TotalLiveBirth = aggregates.LiveLambs,
                    TotalLiveLamb = aggregates.LiveLambs,
                    AliveCount = aggregates.LiveLambs,
                    DeadCount = Math.Max(0, aggregates.TotalLambs - aggregates.LiveLambs)
                },
                Weaning = new WeaningStatsDto
                {
                    TotalWeaned = 0,
                    WeanedLitter = 0,
                    TotalWeight = 0,
                    AverageWeightPerLitter = 0
                }
            };

            return dto;
        }
    }
}
